/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package wwcontroluiclient;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;
import java.util.logging.Logger;
import wwcontrolserver.FieldStationSensorsAndControls;
import wwcontrolserver.WWControlServer;
import wwcontrolserver.WWControlServerState;
import wwcontrolserver.controls.AbstractControl;
import wwcontrolserver.controls.AbstractControlState;
import wwcontrolserver.controls.OnOffControlState;
import wwcontrolserver.controls.DutyCycleControlState;
import wwcontrolserver.controls.SetPointHeaterControlState;

/**
 *
 * @author Michael Ferry
 */
public class WWControlClientCommThread extends Thread {

    private Socket WWControlServerSocket;
    //private PrintWriter outToServer;
    //private BufferedReader inFromServer;
    private ObjectOutputStream OutToServerObj;
    private ObjectInputStream InFromServerObj;
    private WWControlUIClient WWUI;
    private String WWCSip = "localhost";
    //private String WWCSip = "manuresbc.dynamic.ucsd.edu";
    private int ServerPort = WWControlServer.ListenPort;
    //private String WWCSip = "169.228.178.73";

    public WWControlClientCommThread(WWControlUIClient client_arg) {
        super("WWControlCommThread");
        WWUI = client_arg;
    }

    public WWControlServerState RecieveMessage(ObjectInputStream InStream) {
        try {
            try {
                return (WWControlServerState) InStream.readObject();
            } catch (ClassNotFoundException cf) {
                System.out.println(cf);
                //WWCS.RecordLogEntry(cf.toString());
                return null;
            }
        } catch (IOException ex) {
            System.out.println(ex);
            //WWCS.RecordLogEntry(ex.toString());
            return null;
            //Logger.getLogger(WWControlClientCommThread.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void SendMessage(WWControlServerState WWCSStateToServer) {
        try {
//            int x=1;
//            WWCSStateToServer.SetMessageID();
            OutToServerObj.writeObject(WWCSStateToServer);
            OutToServerObj.reset();
            OutToServerObj.flush();
        } catch (IOException ex) {
            System.out.println(ex);
            //Logger.getLogger(WWControlClientCommThread.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public void Disconnect() {
        // try {
        this.SendMessage(new WWControlServerState(WWControlServerState.StateFlags.CLOSE_CONNECTION));
    }

    public void DisconnectAndShutdown() {
        this.SendMessage(new WWControlServerState(WWControlServerState.StateFlags.SHUTDOWN_SERVER));
    }

    @Override
    public void run() {
        //String fromServer, fromUser;
        try {
            WWControlServerState WWCSStateFromServer;
            //WWControlServerState WWCSStateFromServerHolding;
            System.out.println("Attempting to connect to server");
            WWControlServerSocket = new Socket(WWCSip, ServerPort);
            System.out.println("Connected to server");

            OutToServerObj = new ObjectOutputStream(WWControlServerSocket.getOutputStream());
            InFromServerObj = new ObjectInputStream(WWControlServerSocket.getInputStream());

            //Recieve initial state from Server
            WWCSStateFromServer = RecieveMessage(InFromServerObj);
            //Communicate with server until the close connection command is given
            while (WWCSStateFromServer.MessageFlag != WWControlServerState.StateFlags.CLOSE_CONNECTION) {
                ParseServerInput(WWCSStateFromServer);
                WWCSStateFromServer = RecieveMessage(InFromServerObj);
            }

            System.out.println("Server connection ended");

            OutToServerObj.close();
            InFromServerObj.close();
            WWControlServerSocket.close();
        } catch (IOException e) {
            System.out.println(e);
        }
    }
    
    public void ParseServerInput(WWControlServerState WWCSStateToParse) {

        int i=0;
        for(Boolean ifkState: WWCSStateToParse.ifksAttached){
            WWUI.SetIfkUIState(i,ifkState);
            i++;
        }
        if(WWCSStateToParse.StateOfControls != null){
            for(AbstractControlState ControlToProcess: WWCSStateToParse.StateOfControls){
               WWUI.SetControlUIState(ControlToProcess); 
            }
        }
        

    }

    public void SetDataCollectionStateClient(boolean state, long DataCollectionIntervalMilliSeconds){
        WWControlServerState WWCSStateToServer;
        OnOffControlState ToSet = new OnOffControlState(FieldStationSensorsAndControls.DataCollectionCID,null,state);
        WWCSStateToServer = new WWControlServerState(ToSet);

        this.SendMessage(WWCSStateToServer);
        
    }
    public void SetMotorControlStateClient(boolean state, double MotorRunDurationMin, double MotorRunPeriodMin) {
        WWControlServerState WWCSStateToServer;
        DutyCycleControlState ToSet;
        if (state) {
             ToSet = new DutyCycleControlState(FieldStationSensorsAndControls.DigMotorCID, MotorRunDurationMin, MotorRunPeriodMin, TimeUnit.MINUTES);
        } else {
             ToSet = new DutyCycleControlState(FieldStationSensorsAndControls.DigMotorCID, null, DutyCycleControlState.OperationMode.OFF);
        }
            WWCSStateToServer = new WWControlServerState(ToSet);
        this.SendMessage(WWCSStateToServer);
    }
    
    public void SetHeaterControlStateClient(boolean state, int HeaterNumber, double TempSetPoint, double TempSetRange){
        WWControlServerState WWCSStateToServer;
        int HeaterCID = 0;
        switch (HeaterNumber){
            case 0:
                HeaterCID = FieldStationSensorsAndControls.Dig1CID;
                break;
            case 1:
                HeaterCID = FieldStationSensorsAndControls.Dig2CID;
                break;
            case 2:
                HeaterCID = FieldStationSensorsAndControls.Dig3CID;
                break;
            case 3:
                HeaterCID = FieldStationSensorsAndControls.Dig4CID;
                break;
        }
        SetPointHeaterControlState ToSet = new SetPointHeaterControlState(HeaterCID,null,TempSetPoint,TempSetRange,state);
        WWCSStateToServer = new WWControlServerState(ToSet);

        this.SendMessage(WWCSStateToServer);
    }
    public void GetServerStatusClient(){
        WWControlServerState WWCSStateToServer;
        WWCSStateToServer = new WWControlServerState(WWControlServerState.StateFlags.GET_SERVER_STATUS);
        this.SendMessage(WWCSStateToServer);

    }
}